完全二叉树或满二叉树的数组实现(参考性质5)

  二叉树主要有两种实现方式,数组形式和链表形式,其中数组形式是利用完全二叉树的性质5:

性质5:如果对一棵有n个结点的完全二叉树的结点按层序编号,则对任一结点i(1in),有:
  (1)  如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是i/2
  (2)  如果2i>n,则结点i无左孩子;如果2in,则其左孩子是2i
  (3)  如果2i+1>n,则结点i无右孩子;如果2i+1n,则其右孩子是2i+1

来实现的,左边的节点的下标是根节点的下标的2倍,右边的节点的下标是根节点下标的2倍加1。千万要记住这个只能用于完全二叉树(满二叉树其实就是更加完美的完全二叉树),上篇文章写的那种多杈树是用不了的,一般的二叉树也只是有的能用。。(估计很少,就当做不能用吧)。

对应树的操作我用数组实现了树的插入,删除,遍历。因为二叉树是一个完全二叉树,插入以后也要维持完全二叉树的性质,所以看来只能在数组的最后一位插入了。删除的我写了一个从中间节点删的函数,但是感觉实用价值不是很大。

这里是实现代码:

#include<stdio.h>
char src[10]={0,'a','b','c','d','e','f'};//6个元素

int length(char a[]){
    int ret = 1;
    while(a[ret]!=0){ret++;}
    return ret;
}
void insert(char data){

    int srclen = length(src);
    src[srclen] = data;
    
}
void del(int index){
    //把数组index后面的内容都往前面挪一位
    int cur_l = length(src) - 1;
    src[index] = 0;
    for(int i=index;i<cur_l;i++){
        src[i] = src[i+1];
    }
    src[cur_l] = 0;
}
void preorder(int n){
        
    if(n>length(src)){return;}

    printf("%c",src[n]);
    preorder(2*n);
    preorder(2*n+1);

}
void print(){
    int srclength = sizeof(src)/sizeof(char);
    for(int i=0;i<srclength;i++){
        printf("%c",src[i]);
    }
    printf("\n");
}
int main(){
    
    print();
    
    insert('h');
    print();

    del(2);
    print();

    preorder(1);//从1开始

    return 0;
}
sizeof(src)/sizeof(char)这个东西它始终等于的是数组开辟的个数,这里也就是一直等于10.所以不能用它来控制循环的。。。坑
posted @ 2017-09-21 20:11  Pumpkin0227  阅读(1716)  评论(0编辑  收藏  举报